﻿//
// Copyright 2024 Exhunter Technology Co.Ltd2.
//

using System;
using System.Text;
using X18.Framework.Core.Utils;

namespace X18.Framework.Core.Security.Encryptor
{
    /// <summary>
    /// 一般加密算法
    /// </summary>
    public class ProclaimTextEncryptor : IDataEncryptor
    {
        public override byte[] EncryptToBytes(byte[] plainBytes, byte[] key = null)
        {
            if (plainBytes == null || plainBytes.Length <= 0)
            {
                return new byte[0];
            }
            int plainBytesCount = plainBytes.Length;
            byte[] cipherBytes = new byte[plainBytesCount * 2];
            for (int i = 0; i < plainBytesCount; i += 2)
            {
                byte proclaimByte = plainBytes[i];
                int upperByte = (int)(proclaimByte & 240);
                int lowerByte = (int)(proclaimByte & 15);
                upperByte >>= 4;
                lowerByte <<= 4;
                byte proclaimByte2 = plainBytes[i + 1];
                int upperByte2 = (int)(proclaimByte2 & 240);
                int lowerByte2 = (int)(proclaimByte2 & 15);
                upperByte2 |= upperByte;
                lowerByte2 |= lowerByte;
                cipherBytes[i * 2] = 78;
                cipherBytes[i * 2 + 1] = Convert.ToByte(upperByte2);
                cipherBytes[(i + 1) * 2] = 79;
                cipherBytes[(i + 1) * 2 + 1] = Convert.ToByte(lowerByte2);
            }
            return cipherBytes;

        }

        public override byte[] DecryptFromBytes(byte[] cipherBytes, byte[] key = null)
        {
            if (cipherBytes == null || cipherBytes.Length <= 0)
            {
                return new byte[0];
            }
            int cipherBytesCount = cipherBytes.Length;
            byte[] plainBytes = new byte[cipherBytesCount / 2];
            for (int i = 0; i < cipherBytesCount; i += 4)
            {
                byte cipherByte = cipherBytes[i + 1];
                byte cipherByte2 = cipherBytes[i + 3];
                int lowerByte = (int)(cipherByte & 15) << 4;
                int upperByte = (int)(cipherByte & 240);
                int lowerByte2 = (int)(cipherByte2 & 15);
                int upperByte2 = (cipherByte2 & 240) >> 4;
                plainBytes[i / 2] = Convert.ToByte(lowerByte | upperByte2);
                plainBytes[i / 2 + 1] = Convert.ToByte(upperByte | lowerByte2);
            }
            return plainBytes;
        }

        public override string EncryptToString(string plainText, byte[] key = null)
        {
            if (plainText.IsEmpty())
            {
                return string.Empty;
            }
            byte[] plainBytes = Encoding.BigEndianUnicode.GetBytes(plainText);
            byte[] cipherBytes = EncryptToBytes(plainBytes, key);
            return Encoding.BigEndianUnicode.GetString(cipherBytes, 0, cipherBytes.Length);
        }

        public override string DecryptFromString(string cipherText, byte[] key = null)
        {
            if (cipherText.IsEmpty())
            {
                return string.Empty;
            }
            byte[] cipherBytes = Encoding.BigEndianUnicode.GetBytes(cipherText);
            byte[] plainBytes = DecryptFromBytes(cipherBytes, key);
            return Encoding.BigEndianUnicode.GetString(plainBytes, 0, plainBytes.Length);
        }
    }
}
